/*
 * =============================================================================
 * "THE BEER-WARE LICENSE" (Revision 42):
 * <eirikb@google.com> wrote this file. As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a beer in return Eirik Brandtzæg
 * =============================================================================
 */
package no.eirikb.roboco.terminal;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import no.eirikb.roboco.terminal.element.Element;

/**
 *
 * @author eirikb
 * @author <a href="mailto:eirikb@google.com">eirikb@google.com</a>
 */
public class TerminalFileParser {

    private Terminal terminal;
    private int x;
    private int y;

    private enum CODETYPE {

        UNKNOWN, E, ELEMENT;

        public static CODETYPE getCode(String c) {
            try {
                return CODETYPE.valueOf(c);
            } catch (Exception ex) {
            }
            return UNKNOWN;
        }
    }

    public TerminalFileParser(Terminal terminal) {
        this.terminal = terminal;
        x = 1;
        y = 1;
    }

    public void parseFile(String fileName) {
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    new FileInputStream(terminal.getFile().getAbsoluteFile() + File.separator + fileName)));
            String line;
            while ((line = reader.readLine()) != null) {
                String text = line;
                String comment = line.trim();
                if (comment.length() == 0 || (comment.charAt(0) != '#')) {
                    int b1 = line.indexOf("{{");
                    int b2 = line.indexOf("}}");
                    if (b1 >= 0 && b2 >= 0) {
                        x = b1 + 1;
                        text = line.substring(0, b1) + line.substring(b2 + 2);
                        parseCodes(line.substring(b1 + 2, b2).trim());
                    }
                    if (text.length() > 0) {
                        terminal.getServer().sendLagText(text + "\r\n");
                    }
                    y++;
                }
            }
            if (terminal.getElements().size() > 0) {
                terminal.setCurrentElement(terminal.getElements().get(0));
            }

        } catch (IOException ex) {
            Logger.getLogger(Terminal.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void parseCodes(String code) {
        while (code.length() > 0) {
            int b1 = code.indexOf("(");
            int b2 = code.indexOf(")");
            if (b1 >= 0 && b2 >= 0) {
                String cmd = code.substring(0, b1);
                String params = code.substring(b1 + 1, b2);
                code = code.substring(b2 + 1);
                parseCode(cmd, params);
            } else {
                code = "";
            }
        }
    }

    public void parseCode(String code, String params) {
        System.out.println("CODE! " + x + " " + y + ": " + code + " PARAMS: " + params);
        try {
            String pkg = "no.eirikb.roboco.terminal.element.";
            Class cl = Class.forName(pkg + code);
            java.lang.reflect.Constructor constructor = cl.getConstructor(new Class[]{Terminal.class, int.class, int.class, StringTokenizer.class});
            Element e = (Element) constructor.newInstance(terminal, x, y, new StringTokenizer(params, " "));
            terminal.getElements().add(e);
        } catch (Exception ex) {
            error(ex.toString());
            Logger.getLogger(TerminalFileParser.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void error(String error) {
        terminal.getServer().sendLagText("ERROR (line " + y + "): " + error + "\r\n");
    }
}